#include "Random.hh"

Random *Random::instance = NULL;

void Random::init(double seed) {
    values = new double[SIZE];
    for (int i = 0; i < SIZE; i++)
        values[i] = 0.0;

    actual = 0;

    warmup(seed);
}


void Random::warmup(double seed) {

    values[SIZE-1] = seed;
    double next = DEFINITION;
    double prev = seed;

    for (int i = 0; i < SIZE; i++) {
        int j = (21 * i) % (SIZE - 1);
        values[j] = next;
        next = prev - next;

        if (next < 0.0)
            next += 1.0;

        prev = values[i];
    }

    for (int i = 0; i < 3; i++)
        advance();
}

void Random::advance() {

    double next;

    for (int i = 0; i < 24; i++) {

        next = values[i] - values[i + 31];
        if (next < 0.0)
            next += 1.0;

        values[i] = next;
    }

    for (int i = 24; i < SIZE; i++) {
        next = values[i] - values[i-24];
        if (next < 0.0)
            next += 1.0;

        values[i] = next;
    }
}
/**@return a random value between 0.0 and 1.0*/
double Random::random() {
    actual++;

    if (actual >= SIZE) {
        actual = 1;
        advance();
    }

    return values[actual];
}

